using System;
using System.Linq;
using Anno.Loader;
using Anno.Log;
using Autofac;
using Anno.Const;
using Anno;

namespace AnnoWcfService
{
    using Anno.EngineData;
    using Anno.Rpc.Server;
    using System.IO;
    using System.Reflection;

    static class Program
    {
        static void Main(string[] args)
        {
            if (args.Contains("-help"))
            {
                Log.WriteLineAlignNoDate(@"
启动参数：
                -p     6659                    设置启动端口
                -xt    200                     设置服务最大线程数
                -t     20000                   设置超时时间（单位毫秒）
                -w     1                       设置权重
                -h     192.168.0.2             设置服务在注册中心的地址
                -tr    false                   设置调用链追踪是否启用
                --reg  false                   重新注册服务
");
                return;
            }
           Assemblys.AddOtherPlugsAssembly.Add(AddOtherPlugsAssembly);
           Assemblys.RegisterOtherAssembly.Add(RegisterOtherAssembly);
           Assemblys.BuilderOtherRouterInfo.Add(BuilderOtherRouterInfo);

            /**
             * 启动默认DI库为 Autofac 可以切换为微软自带的DI库 DependencyInjection
             */
            Bootstrap.StartUp(args, () =>//服务配置文件读取完成后回调(服务未启动)
            {
                Anno.Const.SettingService.TraceOnOff = true;

                /*
                 * 功能插件选择是Thrift还是 Grpc
                 * Install-Package Anno.Rpc.Client -Version 1.0.2.6 Thrift
                 * Install-Package Anno.Rpc.ServerGrpc -Version 1.0.1.5 Grpc
                 * 此处为 Thrift
                 */
                var autofac = IocLoader.GetAutoFacContainerBuilder();
                #region 自带依赖注入过滤器 true  注入 false 不注入
                //IocLoader.AddFilter((type) =>
                //       {
                //           return true;
                //       });
                #endregion
                /**
                 * IRpcConnector 是Anno.EngineData 内置的服务调用接口
                 * 例如：this.InvokeProcessor("Anno.Plugs.SoEasy", "AnnoSoEasy", "SayHi", input)
                 * IRpcConnector 接口用户可以自己实现也可以使用 Thrift或者Grpc Anno内置的实现
                 * 此处使用的是Thrift的实现
                 */
                autofac.RegisterType(typeof(RpcConnectorImpl)).As(typeof(IRpcConnector)).SingleInstance();
            }
            , () =>//服务启动后的回调方法
            {
                /**
                 * 服务Api文档写入注册中心
                 */
                Bootstrap.ApiDoc();
            });
        }

        /// <summary>
        /// 添加扩展Assembly
        /// </summary>
        static void AddOtherPlugsAssembly()
        {
            #region Wcf Packages 目录 插件
#if NETFRAMEWORK
            var wcfBasePath = Path.Combine(Directory.GetCurrentDirectory(), "WcfPackages");
            Console.WriteLine($"wcfBasePath：{wcfBasePath}");
            if (Directory.Exists(wcfBasePath))
            {
                foreach (DirectoryInfo plugInfo in new DirectoryInfo(wcfBasePath).GetDirectories())
                {
                    try
                    {
                        var plugName = plugInfo.Name; //$"Anno.Plugs.SerialRule";
                        var plugNameService = $"{plugName}";
                        var plugsPath = Path.Combine(wcfBasePath, plugName, $"{plugNameService}.dll");
                        Console.WriteLine($"WcfPlugsPath：{plugsPath}");
                        if (File.Exists(plugsPath))
                        {
                            var assembly = Assembly.UnsafeLoadFrom(plugsPath); //装载组件
                            if (!Anno.Const.Assemblys.Dic.ContainsKey(plugNameService))
                            {
                                Anno.Const.Assemblys.Dic.Add($"{plugNameService}", assembly);
                                if (!string.IsNullOrEmpty(Anno.Const.SettingService.FuncName))
                                {
                                    Anno.Const.SettingService.FuncName += ",";
                                }
                                Anno.Const.SettingService.FuncName += plugNameService;
                                Console.WriteLine($"FuncName：{Anno.Const.SettingService.FuncName}");
                            }
                            if (Anno.Const.AppSettings.IocDll.All(plug => plug != plugNameService))
                            {
                                Anno.Const.AppSettings.IocDll.Add(plugNameService);
                                Console.WriteLine($"AppSettings.IocDll.Count：{Anno.Const.AppSettings.IocDll.Count}");
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine($"插件【{plugInfo.Name}】加载出错！");
                        Console.WriteLine($"错误信息：");
                        Console.WriteLine(ex.Message);
                    }
                }
            }
#endif
            #endregion
        }
        /// <summary>
        /// 注册WCF服务
        /// </summary>
        /// <param name="builder"></param>
        /// <param name="assembly"></param>
        /// <param name="lifetime"></param>
        /// <param name="t"></param>
        static void RegisterOtherAssembly(ContainerBuilder builder, Assembly assembly, string lifetime, Type t)
        {
            //注册WCF服务
            if (t.GetCustomAttribute<System.ServiceModel.ServiceContractAttribute>() != null)
            {
                if (t.IsGenericType)
                {
                    switch (lifetime)
                    {
                        case "Singleton":
                            builder.RegisterGeneric(t).SingleInstance();
                            break;
                        case "Scoped":
                            builder.RegisterGeneric(t).InstancePerLifetimeScope();
                            break;
                        default:
                            builder.RegisterGeneric(t);
                            break;
                    }
                }
                else
                {
                    switch (lifetime)
                    {
                        case "Singleton":
                            builder.RegisterType(t).SingleInstance();
                            break;
                        case "Scoped":
                            builder.RegisterType(t).InstancePerLifetimeScope();
                            break;
                        default:
                            builder.RegisterType(t);
                            break;
                    }
                }
            }
        }
        /// <summary>
        /// 构建路由信息
        /// </summary>
        /// <param name="svc"></param>
        static void BuilderOtherRouterInfo(Assembly svc, Type baseModuleType)
        {
            svc.GetTypes().Where(x => x.GetInterfaces()?.Length > 0
                 && x.GetInterfaces().Where(s => s.GetCustomAttribute<System.ServiceModel.ServiceContractAttribute>() != null).Any()
                 && x.GetTypeInfo().IsClass && !x.GetTypeInfo().IsAbstract && !x.GetTypeInfo().IsInterface
                 && !baseModuleType.IsAssignableFrom(x))?.ToList().ForEach(t =>
                 {
                     var methods = t.GetMethods().Where(m => !m.DeclaringType.Equals(typeof(object)) && m.IsPublic);
                     foreach (var method in methods)
                     {
                         var routInfo = new Anno.EngineData.Routing.RoutInfo()
                         {
                             RoutMethod = method,
                             RoutModuleType = t
                         };
                         #region Authorization Filters
                         // /*
                         //* 全局过滤器
                         //*/
                         // routInfo.AuthorizationFilters.AddRange(Routing.Routing.GlobalAuthorizationFilters);
                         // /*
                         // * 模块过滤器
                         // */
                         // routInfo.AuthorizationFilters.AddRange(t.GetAnnoCustomAttributes<IAuthorizationFilter>());
                         // /*
                         // * 方法过滤器
                         // */
                         // routInfo.AuthorizationFilters.AddRange(method.GetAnnoCustomAttributes<IAuthorizationFilter>());
                         #endregion
                         #region Action Filters
                         ///*
                         //* 全局过滤器
                         //*/
                         //routInfo.ActionFilters.AddRange(Routing.Routing.GlobalActionFilters);
                         ///*
                         //* 模块过滤器
                         //*/
                         //routInfo.ActionFilters.AddRange(routInfo.RoutModuleType.GetAnnoCustomAttributes<IActionFilter>());
                         ///*
                         //* 方法过滤器
                         //*/
                         //routInfo.ActionFilters.AddRange(routInfo.RoutMethod.GetAnnoCustomAttributes<IActionFilter>());

                         #endregion
                         #region Exception Filters
                         // /*
                         //* 方法过滤器
                         //*/
                         // routInfo.ExceptionFilters.AddRange(routInfo.RoutMethod.GetAnnoCustomAttributes<IExceptionFilter>());
                         // /*
                         // * 模块过滤器
                         // */
                         // routInfo.ExceptionFilters.AddRange(routInfo.RoutModuleType.GetAnnoCustomAttributes<IExceptionFilter>());
                         // /*
                         //  * 全局过滤器
                         //  */
                         // routInfo.ExceptionFilters.AddRange(Routing.Routing.GlobalExceptionFilters);
                         #endregion
                         #region CacheMiddleware 
                         ///*
                         // * 全局Cache
                         //*/
                         //routInfo.CacheMiddleware.AddRange(Routing.Routing.GlobalCacheMiddleware);
                         ///*
                         // * 模块Cache
                         //*/
                         //routInfo.CacheMiddleware.AddRange(routInfo.RoutModuleType.GetCustomAttributes<Cache.CacheMiddlewareAttribute>());
                         ///*
                         // * 方法Cache
                         //*/
                         //routInfo.CacheMiddleware.AddRange(routInfo.RoutMethod.GetCustomAttributes<Cache.CacheMiddlewareAttribute>());
                         #endregion

                         //var key = $"{t.FullName}/{method.Name}";
                         //if (Anno.EngineData.Routing.Routing.Router.ContainsKey(key))
                         //{
                         //    Anno.EngineData.Routing.Routing.Router[key] = routInfo;
                         //}
                         //else
                         //{
                         //    Anno.EngineData.Routing.Routing.Router.TryAdd(key, routInfo);
                         //}
                         Anno.EngineData.Routing.Routing.AddRoutInfo(routInfo);
                     }
                    
                     //处理 FuncPath
                     t.SetFuncPath();
                 });
        }
    }
}
